import { doAnimationFrame, abortAnimationFrame } from './requestAnimationFrame.js'
const { globalData } = getApp();
class Animation {
  constructor(props) {
    this.playStatus = props.event == 'auto' ? 'ready' : 'ide'; //播放状态 ide=初始化 ready=准备播放 playing=播放中 ended=播放结束
    this.duration = props.duration.duration * 1000;  //动画持续时间
    this.delay = props.delay.delay * 1000; //动画延迟时间
    this.styles = props.styles; //动画的css属性数组
    this.loop = props.loop.loop; //动画是否循环
    this.second = props.second.second; //动画播放次数
    this.eventType = props.event; //动画的播放方式   'auto'=自动播放
    this.playMode = props.playMode; //动画是否首尾连接播放  true为开始到结束到开始 false为从开始到结束
    this.isOnePlay = true; //动画第一次播放的话 需要动画到初始位置
    this.initialization = props.initialization; //是否需要直接初始化动画开始
    this.animateThis = null;
  }

  //初始化动画属性
  initStartAttr = (attr) => {
    let transform = [];
    let startStyles = {};
    this.styles.map((item, index) => {
      switch (item.style) {
        case 'scale':
          transform.push(`scale(${item[attr]})`);
          break
        case 'translateX':
          transform.push(`translateX(${item[attr] / globalData.radio})`)
          break
        case 'translateY':
          transform.push(`translateY(${item[attr] / globalData.radio})`)
          break
        case 'rotate':
          transform.push(`rotate(${item[attr]})`)
          break
        default:
          startStyles[item.style] = item[attr]
          break;
      }
    })
    startStyles['transform'] = transform;
    return startStyles
  }
  /**
   * 
   * @param {*} loop 如果播放次数大于一  播放完毕后 重置为ready状态 
   */
  play(loop) {
    let startAttrObj = this.initStartAttr('start')
    let endAttrObj = this.initStartAttr('end')
    this.playStatus = 'playing'
    globalData.animateStartTime = new Date().getTime();
    if (this.playMode) {
      this.playModeAll(startAttrObj, endAttrObj, loop)
    } else {
      this.playModeOne(startAttrObj, endAttrObj, loop)
    }
  };
  // timediff(start,duration){
  //   let  animateEndTime=start+duration;
  //     return animateEndTime;
  //  }
  //播放方式  单次从开始到结束
  playModeOne(startAttrObj, endAttrObj, loop) {
    setTimeout(() => {
      var animation = my.createAnimation({
        transformOrigin: "center center",
        duration: 0,
        timeFunction: "linear",
        delay: 0,
      })
      let startAniData = startAttrObj.transform;
      this.currentAnimation(animation, startAniData)
      animation.step({ duration: 0 });
      this.animateThis.setData({
        chanel: animation.export()
      });
    },
      this.initialization ? 0 : this.delay)
    setTimeout(() => {
      var animation = my.createAnimation({
        transformOrigin: "center center",
        duration: this.duration,
        timeFunction: "linear",
        delay: 0,
      })
      let endAniData = endAttrObj.transform;
      this.currentAnimation(animation, endAniData)
      animation.step();
      this.animateThis.setData({
        chanel: animation.export()
      });
    }, this.delay + 100)
    //计算动画完成时间
    // this. animateEndTime=this.timediff(globalData.animateStartTime,this.duration);
    this.playStatus = loop ? 'ready' : 'ended';
    this.OneTimeout = setTimeout(() => {
      if (loop) {
        this.OnerequestID = doAnimationFrame(this.process.bind(this, this.animateThis))
      }
    }, this.duration * 1.29)
  }

  //添加动画数据
  currentAnimation(animation, data) {
    data.length > 0 && data.map((item, index) => {
      for (let i = 0; i < item.length; i++) {
        if (item.charAt(i) == "(") {
          let animationType = item.substr(0, i)
          let animationValue = item.substr(i).substring(1, item.substr(i).length - 1)
          let newAnimationValue = []
          let news = animationValue.split(",")
          for (let j = 0; j < news.length; j++) {
            newAnimationValue.push(Number(news[j]))
          }
          let newFinAnimationValue = []
          newFinAnimationValue.push(animationType, newAnimationValue)
          animation.currentAnimation.push(newFinAnimationValue)

        }
      }
    })
  }
  //首尾循环播放
  playModeAll(startAttrObj, endAttrObj, loop) {
    if (this.initialization) {
      setTimeout(() => {
        var animation = my.createAnimation({
          transformOrigin: "center center",
          duration: this.isOnePlay ? this.duration / 2 : 1,
          timeFunction: "linear",
          delay: 0,
        })
        let startAniData = startAttrObj.transform;

        this.currentAnimation(animation, startAniData)
        animation.step();
        this.animateThis.setData({
          chanel: animation.export()
        });
        this.isOnePlay = false
      }, 0)
    } else {
      setTimeout(() => {
        var animation = my.createAnimation({
          transformOrigin: "center center",
          duration: 0,
          timeFunction: "linear",
          delay: 0,
        })
        let startAniData = startAttrObj.transform;
        this.currentAnimation(animation, startAniData)
        animation.step();
        this.animateThis.setData({
          chanel: animation.export()
        });
        this.isOnePlay = false;
      }, 0)
    }
    setTimeout(() => {
      var animation = my.createAnimation({
        transformOrigin: "center center",
        duration: this.duration / 2,
        timeFunction: "ease",
        delay: 0,
      })
      let endAniData = endAttrObj.transform;
      this.currentAnimation(animation, endAniData)
      animation.step();
      this.animateThis.setData({
        chanel: animation.export()
      });
    }, this.isOnePlay ? this.delay + 100 : 100)
    //计算动画完成时间
    this.playStatus = this.playMode ? 'ready' : 'ended';
    setTimeout(() => {
      var animation = my.createAnimation({
        transformOrigin: "center center",
        duration: this.duration / 2,
        timeFunction: "ease",
        delay: 0,
      })
      let startAniData = startAttrObj.transform;
      this.currentAnimation(animation, startAniData)

      animation.step();
      this.animateThis.setData({
        chanel: animation.export()
      });
      this.AllTimeout = setTimeout(() => {
        this.AllrequestID = doAnimationFrame(this.process.bind(this, this.animateThis))
      }, this.duration / 2)
    }, this.duration)
  };

  //条件判断播放
  process(that) {
    this.animateThis = that;
    if (this.playStatus == 'ready') {
      this.playCondition();
    }
  }
  //播放条件
  playCondition() {
    if (!this.loop) {
      if (this.playStatus == 'playing') return;
      if (this.second <= 1) { this.play(false); return; }
      this.second -= 1;
      this.play(true);
    } else {  //如果动画是循环的话
      if (this.playStatus != 'playing') {  //如果当前状态不在播放中
        this.play(true);
      }
    }
  };
}
export { process }
export default Animation;

